package xdu.lz.stage1_basic.chapter1_threadsafe.synchronize;

class SynchronizedStaticLock{

    static {
        synchronized (SynchronizedLock.class){
            try {
                Thread.sleep(2000L);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
    public static synchronized void m1(){
        System.out.println("m1 start");
        System.out.println("current thread:"+Thread.currentThread().getName());
        try {
            Thread.sleep(1000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

    }
    public static synchronized void m2(){
        System.out.println("m2 start");
        System.out.println("current thread:"+Thread.currentThread().getName());
        try {
            Thread.sleep(1000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

    }
    public static void m3(){
        System.out.println("m3 start");
        System.out.println("current thread:"+Thread.currentThread().getName());
        try {
            Thread.sleep(1000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
    public synchronized void m4(){
        System.out.println("m4 start");
        System.out.println("current thread:"+Thread.currentThread().getName());
        try {
            Thread.sleep(1000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}

public class SynchronizedStaticTest {
    public static void main(String[] args) {
        //静态方法的synchronized锁的对象的 对象的字节码文件，是唯一的，是公用的，不管实例出几个对象
        SynchronizedStaticLock lock1 = new SynchronizedStaticLock();
        SynchronizedStaticLock lock2 = new SynchronizedStaticLock();
        //lock1和lock2调用m1、m2的锁都是SynchronizedStaticLock.class

        //但是注意m4是非静态方法，其锁是lock1实例对象，和SynchronizedStaticLock.class不是一个东西
        //所以t3 、t4和  t1或t2中的一个同时执行，然后执行剩下的那个
        new Thread(()->{
            lock1.m1();
        },"t1").start();
        new Thread(()->{
            lock2.m2();
        },"t2").start();
        new Thread(()->{
            SynchronizedStaticLock.m3();
        },"t3").start();
        new Thread(()->{
            lock1.m4();
        },"t4").start();
    }
}
